Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / tests / backend / test_web_audio_bridge.py

Displaying Raw • Download


tests/backend/test_web_audio_bridge.py v4.7.0-rc.4 (448cd46c) Text, 16.08 KB

T8b949e# SPDX-License-Identifier: 0BSD

Tff7b72import T7ee787asyncio
Tff7b72import T7ee787json
Tff7b72from T7ee787unittestT7ee787.T7ee787mock Tff7b72import Te6edf3AsyncMockTb4b4b4, Te6edf3MagicMockTb4b4b4, Te6edf3patch

Tff7b72import T7ee787numpy Tff7b72as T7ee787np
Tff7b72import T7ee787pytest

Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787web_audio_bridge Tff7b72import Tb4b4b4(
Te6edf3WebAudioBridgeTb4b4b4,
Te6edf3WebAudioSinkTb4b4b4,
Te6edf3WebAudioSourceTb4b4b4,
Tb4b4b4)


Tff7b72class T56d364_DummySinkTb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffframes Tff7b72= Tb4b4b4[Tb4b4b4]

Tff7b72def Td2a8ffcan_receiveTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3from_sourceTff7b72=Tff7b72NoneTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True

Tff7b72def Td2a8ffhandle_frameTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3frameTb4b4b4, Te6edf3sourceTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffframesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3frameTb4b4b4)


Tff7b72def Td2a8fftest_web_audio_source_pushes_framesTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3sink Tff7b72= Te6edf3_DummySinkTb4b4b4(Tb4b4b4)
Te6edf3src Tff7b72= Te6edf3WebAudioSourceTb4b4b4(Te6edf3target_frame_msTff7b72=T79c0ff60Tb4b4b4, Te6edf3sinkTff7b72=Te6edf3sinkTb4b4b4)
Te6edf3zeros Tff7b72= Te6edf3npTff7b72.Td2a8ffzerosTb4b4b4(T79c0ff160Tb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8ffint16Tb4b4b4)
Te6edf3srcTff7b72.Td2a8ffpush_pcmTb4b4b4(Te6edf3zerosTff7b72.Td2a8fftobytesTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3sinkTff7b72.Td2a8ffframesTb4b4b4) Tff7b72== T79c0ff1


Tff7b72def Td2a8fftest_web_audio_source_empty_pcm_does_not_pushTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3sink Tff7b72= Te6edf3_DummySinkTb4b4b4(Tb4b4b4)
Te6edf3src Tff7b72= Te6edf3WebAudioSourceTb4b4b4(Te6edf3target_frame_msTff7b72=T79c0ff60Tb4b4b4, Te6edf3sinkTff7b72=Te6edf3sinkTb4b4b4)
Te6edf3srcTff7b72.Td2a8ffpush_pcmTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3sinkTff7b72.Td2a8ffframesTb4b4b4) Tff7b72== T79c0ff0


Tff7b72def Td2a8fftest_web_audio_source_respects_sink_can_receive_falseTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3sink Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3sinkTff7b72.Td2a8ffcan_receiveTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72False
Te6edf3src Tff7b72= Te6edf3WebAudioSourceTb4b4b4(Te6edf3target_frame_msTff7b72=T79c0ff60Tb4b4b4, Te6edf3sinkTff7b72=Te6edf3sinkTb4b4b4)
Te6edf3srcTff7b72.Td2a8ffpush_pcmTb4b4b4(Te6edf3npTff7b72.Td2a8ffzerosTb4b4b4(T79c0ff8Tb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8ffint16Tb4b4b4)Tff7b72.Td2a8fftobytesTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3sinkTff7b72.Td2a8ffhandle_frameTff7b72.Td2a8ffassert_not_calledTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8fftest_web_audio_source_can_receive_and_handle_frame_are_safeTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3sink Tff7b72= Te6edf3_DummySinkTb4b4b4(Tb4b4b4)
Te6edf3src Tff7b72= Te6edf3WebAudioSourceTb4b4b4(Te6edf3target_frame_msTff7b72=T79c0ff0Tb4b4b4, Te6edf3sinkTff7b72=Te6edf3sinkTb4b4b4)
Tff7b72assert Te6edf3srcTff7b72.Td2a8ffcan_receiveTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72True
Te6edf3srcTff7b72.Td2a8ffhandle_frameTb4b4b4(Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4)


Tff7b72def Td2a8fftest_web_audio_sink_encodes_and_sends_bytesTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3loop Tff7b72= Te6edf3asyncioTff7b72.Td2a8ffnew_event_loopTb4b4b4(Tb4b4b4)
Te6edf3asyncioTff7b72.Td2a8ffset_event_loopTb4b4b4(Te6edf3loopTb4b4b4)
Te6edf3sent Tff7b72= Tb4b4b4[Tb4b4b4]

Tff7b72async Tff7b72def Td2a8ff_send_bytesTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Te6edf3sentTff7b72.Td2a8ffappendTb4b4b4(Te6edf3dataTb4b4b4)

Te6edf3sink Tff7b72= Te6edf3WebAudioSinkTb4b4b4(Te6edf3loopTb4b4b4, Te6edf3_send_bytesTb4b4b4)
Te6edf3sinkTff7b72.Td2a8ffhandle_frameTb4b4b4(Te6edf3npTff7b72.Td2a8ffzerosTb4b4b4(Tb4b4b4(T79c0ff160Tb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4)Tb4b4b4, Tff7b72NoneTb4b4b4)
Te6edf3loopTff7b72.Td2a8ffrun_until_completeTb4b4b4(Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.01Tb4b4b4)Tb4b4b4)
Te6edf3loopTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3sentTb4b4b4, Ta5d6ff"Ta5d6ffexpected audio bytes to be queued for sendingTa5d6ff"


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_web_audio_sink_forwards_non_numpy_frame_unchangedTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3sent Tff7b72= Tb4b4b4[Tb4b4b4]

Tff7b72async Tff7b72def Td2a8ff_send_bytesTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Te6edf3sentTff7b72.Td2a8ffappendTb4b4b4(Te6edf3dataTb4b4b4)

Te6edf3sink Tff7b72= Te6edf3WebAudioSinkTb4b4b4(Te6edf3asyncioTff7b72.Td2a8ffget_running_loopTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_send_bytesTb4b4b4)
Te6edf3sinkTff7b72.Td2a8ffhandle_frameTb4b4b4(Ta5d6ffbTa5d6ff"Tffea00\xffTffea00\x00Ta5d6ff"Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.02Tb4b4b4)
Tff7b72assert Te6edf3sent Tff7b72== Tb4b4b4[Ta5d6ffbTa5d6ff"Tffea00\xffTffea00\x00Ta5d6ff"Tb4b4b4]


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_web_audio_sink_numpy_frame_clips_to_int16_rangeTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3sent Tff7b72= Tb4b4b4[Tb4b4b4]

Tff7b72async Tff7b72def Td2a8ff_send_bytesTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4:
Te6edf3sentTff7b72.Td2a8ffappendTb4b4b4(Te6edf3dataTb4b4b4)

Te6edf3sink Tff7b72= Te6edf3WebAudioSinkTb4b4b4(Te6edf3asyncioTff7b72.Td2a8ffget_running_loopTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3_send_bytesTb4b4b4)
Te6edf3arr Tff7b72= Te6edf3npTff7b72.Td2a8ffarrayTb4b4b4(Tb4b4b4[Tb4b4b4[T79c0ff2.0Tb4b4b4]Tb4b4b4, Tb4b4b4[Tff7b72-T79c0ff2.0Tb4b4b4]Tb4b4b4]Tb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8fffloat32Tb4b4b4)
Te6edf3sinkTff7b72.Td2a8ffhandle_frameTb4b4b4(Te6edf3arrTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.02Tb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3sentTb4b4b4) Tff7b72== T79c0ff1
Te6edf3out Tff7b72= Te6edf3npTff7b72.Td2a8fffrombufferTb4b4b4(Te6edf3sentTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3dtypeTff7b72=Te6edf3npTff7b72.Td2a8ffint16Tb4b4b4)
Tff7b72assert Te6edf3outTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== T79c0ff32767
Tff7b72assert Te6edf3outTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72== Tff7b72-T79c0ff32767


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_web_audio_bridge_lazy_loopTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""Test that WebAudioBridge retrieves the loop lazily to avoid startup crashes."""
Te6edf3mock_tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3mock_config_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)

T8b949e# Mock get_event_loop to simulate it not being available during init
Tff7b72with Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffasyncio.get_event_loopTa5d6ff"Tb4b4b4, Te6edf3side_effectTff7b72=Tf85149RuntimeErrorTb4b4b4(Ta5d6ff"Ta5d6ffNo running loopTa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4:
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3mock_tele_mgrTb4b4b4, Te6edf3mock_config_mgrTb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ff_loop Tff7b72is Tff7b72None

T8b949e# Simulate a running loop
Te6edf3current_loop Tff7b72= Te6edf3asyncioTff7b72.Td2a8ffget_running_loopTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffloop Tff7b72== Te6edf3current_loop
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ff_loop Tff7b72== Te6edf3current_loop


Tff7b72def Td2a8fftest_web_audio_config_enabled_follows_telephone_web_audio_flagTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3cfg Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3cfgTff7b72.Td2a8fftelephone_web_audio_enabledTff7b72.Td2a8ffgetTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72True
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Tff7b72NoneTb4b4b4, Te6edf3cfgTb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffconfig_enabledTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72True
Te6edf3cfgTff7b72.Td2a8fftelephone_web_audio_enabledTff7b72.Td2a8ffgetTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72False
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffconfig_enabledTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72False


Tff7b72def Td2a8fftest_web_audio_config_disabled_without_config_managerTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72assert Tff7b72not Te6edf3bridgeTff7b72.Td2a8ffconfig_enabledTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8fftest_web_audio_config_enabled_false_without_flag_attributeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72class T56d364_CfgTb4b4b4:
Tff7b72pass

Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Tff7b72NoneTb4b4b4, Te6edf3_CfgTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffconfig_enabledTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72False


Tff7b72def Td2a8fftest_web_audio_allow_fallback_follows_configTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3cfg Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3cfgTff7b72.Td2a8fftelephone_web_audio_allow_fallbackTff7b72.Td2a8ffgetTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72True
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Tff7b72NoneTb4b4b4, Te6edf3cfgTb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffallow_fallbackTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72True
Te6edf3cfgTff7b72.Td2a8fftelephone_web_audio_allow_fallbackTff7b72.Td2a8ffgetTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72False
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffallow_fallbackTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72False


Tff7b72def Td2a8fftest_web_audio_allow_fallback_false_without_flag_attributeTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72class T56d364_CfgTb4b4b4:
Tff7b72pass

Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Tff7b72NoneTb4b4b4, Te6edf3_CfgTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffallow_fallbackTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72False


Tff7b72def Td2a8fftest_web_audio_bridge_asyncutils_fallbackTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""Test that WebAudioBridge falls back to AsyncUtils.main_loop if no loop is running."""
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787async_utils Tff7b72import Te6edf3AsyncUtils

Te6edf3AsyncUtilsTff7b72.Td2a8ffmain_loop Tff7b72= Tff7b72None
Te6edf3AsyncUtilsTff7b72.Td2a8ff_pending_coroutinesTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)

Te6edf3mock_loop Tff7b72= Te6edf3MagicMockTb4b4b4(Te6edf3specTff7b72=Te6edf3asyncioTff7b72.Td2a8ffAbstractEventLoopTb4b4b4)
Te6edf3mock_loopTff7b72.Td2a8ffis_runningTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72False
Te6edf3AsyncUtilsTff7b72.Td2a8ffset_main_loopTb4b4b4(Te6edf3mock_loopTb4b4b4)

Te6edf3mock_tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3mock_config_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)

Tff7b72with Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffasyncio.get_running_loopTa5d6ff"Tb4b4b4, Te6edf3side_effectTff7b72=Tf85149RuntimeErrorTb4b4b4)Tb4b4b4:
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3mock_tele_mgrTb4b4b4, Te6edf3mock_config_mgrTb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffloop Tff7b72== Te6edf3mock_loop
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ff_loop Tff7b72== Te6edf3mock_loop


Tff7b72def Td2a8fftest_attach_client_returns_false_without_active_callTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8fftelephone Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8fftelephoneTff7b72.Td2a8ffactive_call Tff7b72= Tff7b72None
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3mock_client Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3attached Tff7b72= Te6edf3bridgeTff7b72.Td2a8ffattach_clientTb4b4b4(Te6edf3mock_clientTb4b4b4)

Tff7b72assert Te6edf3attached Tff7b72is Tff7b72False
Tff7b72assert Te6edf3mock_client Tff7b72not Tff7b72in Te6edf3bridgeTff7b72.Td2a8ffclients


Tff7b72class T56d364_TeleMgrNoTelephoneTb4b4b4:
T8b949e"""Telephone manager shape without a ``telephone`` attribute (edge case)."""


Tff7b72def Td2a8fftest_tele_returns_none_when_manager_has_no_telephoneTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3_TeleMgrNoTelephoneTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ff_teleTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72None


Tff7b72def Td2a8fftest_push_client_frame_no_op_without_tx_sourceTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8fftx_source Tff7b72= Tff7b72None
Te6edf3bridgeTff7b72.Td2a8ffpush_client_frameTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffignoredTa5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_push_client_frame_forwards_to_tx_sourceTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8ffis_voicemail_session_active Tff7b72= Tff7b72False
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3mock_tx Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8fftx_source Tff7b72= Te6edf3mock_tx
Te6edf3bridgeTff7b72.Td2a8ffpush_client_frameTb4b4b4(Ta5d6ffbTa5d6ff"Tffea00\x01Tffea00\x02Ta5d6ff"Tb4b4b4)
Te6edf3mock_txTff7b72.Td2a8ffpush_pcmTff7b72.Td2a8ffassert_called_once_withTb4b4b4(Ta5d6ffbTa5d6ff"Tffea00\x01Tffea00\x02Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_push_client_frame_drops_during_voicemailTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8ffis_voicemail_session_active Tff7b72= Tff7b72True
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3mock_tx Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8fftx_source Tff7b72= Te6edf3mock_tx
Te6edf3bridgeTff7b72.Td2a8ffpush_client_frameTb4b4b4(Ta5d6ffbTa5d6ff"Tffea00\x01Tffea00\x02Ta5d6ff"Tb4b4b4)
Te6edf3mock_txTff7b72.Td2a8ffpush_pcmTff7b72.Td2a8ffassert_not_calledTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8fftest_attach_client_returns_false_during_voicemailTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3tele Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8ffactive_call Tff7b72= Tffa657objectTb4b4b4(Tb4b4b4)
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8fftelephone Tff7b72= Te6edf3tele
Te6edf3tele_mgrTff7b72.Td2a8ffis_voicemail_session_active Tff7b72= Tff7b72True
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffattach_clientTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False


Tff7b72def Td2a8fftest_ensure_remote_tx_skips_during_voicemailTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3tele Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8fftelephone Tff7b72= Te6edf3tele
Te6edf3tele_mgrTff7b72.Td2a8ffis_voicemail_session_active Tff7b72= Tff7b72True
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ff_ensure_remote_txTb4b4b4(Te6edf3teleTb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8fftx_source Tff7b72is Tff7b72None


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_send_status_uses_tele_frame_msTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3tele Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8fftarget_frame_time_ms Tff7b72= T79c0ff52
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8fftelephone Tff7b72= Te6edf3tele
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3client Tff7b72= Te6edf3AsyncMockTb4b4b4(Tb4b4b4)
Tff7b72await Te6edf3bridgeTff7b72.Td2a8ffsend_statusTb4b4b4(Te6edf3clientTb4b4b4)
Te6edf3payload Tff7b72= Te6edf3jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3clientTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_argsTff7b72.Td2a8ffargsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)
Tff7b72assert Te6edf3payload Tff7b72== Tb4b4b4{Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffweb_audio.readyTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffframe_msTa5d6ff"Tb4b4b4: T79c0ff52Tb4b4b4}


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_send_status_defaults_frame_ms_when_missingTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3tele Tff7b72= Te6edf3MagicMockTb4b4b4(Te6edf3specTff7b72=Tb4b4b4[Ta5d6ff"Ta5d6ffactive_callTa5d6ff"Tb4b4b4]Tb4b4b4)
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8fftelephone Tff7b72= Te6edf3tele
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3client Tff7b72= Te6edf3AsyncMockTb4b4b4(Tb4b4b4)
Tff7b72await Te6edf3bridgeTff7b72.Td2a8ffsend_statusTb4b4b4(Te6edf3clientTb4b4b4)
Te6edf3payload Tff7b72= Te6edf3jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3clientTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_argsTff7b72.Td2a8ffargsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)
Tff7b72assert Te6edf3payloadTb4b4b4[Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffweb_audio.readyTa5d6ff"
Tff7b72assert Te6edf3payloadTb4b4b4[Ta5d6ff"Ta5d6ffframe_msTa5d6ff"Tb4b4b4] Tff7b72== T79c0ff60


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_send_status_defaults_when_no_telephoneTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3_TeleMgrNoTelephoneTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3client Tff7b72= Te6edf3AsyncMockTb4b4b4(Tb4b4b4)
Tff7b72await Te6edf3bridgeTff7b72.Td2a8ffsend_statusTb4b4b4(Te6edf3clientTb4b4b4)
Te6edf3payload Tff7b72= Te6edf3jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3clientTff7b72.Td2a8ffsend_strTff7b72.Td2a8ffawait_argsTff7b72.Td2a8ffargsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)
Tff7b72assert Te6edf3payload Tff7b72== Tb4b4b4{Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffweb_audio.readyTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffframe_msTa5d6ff"Tb4b4b4: T79c0ff60Tb4b4b4}


Tf0883e@patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.web_audio_bridge.PipelineTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_attach_client_success_wires_telephony_and_dedupes_clientTb4b4b4(Te6edf3mock_pipeline_clsTb4b4b4)Tb4b4b4:
T8b949e"""LXST ``Pipeline`` validates sources; mock it so we only assert bridge wiring."""
Te6edf3mock_receive_pipeline Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3mock_pipeline_clsTff7b72.Td2a8ffreturn_value Tff7b72= Te6edf3mock_receive_pipeline
Te6edf3tele Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8ffactive_call Tff7b72= Tffa657objectTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8fftarget_frame_time_ms Tff7b72= T79c0ff48
Te6edf3teleTff7b72.Td2a8ffaudio_input Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8fftransmit_mixer Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8fftransmit_mixerTff7b72.Td2a8ffshould_run Tff7b72= Tff7b72False
Te6edf3teleTff7b72.Td2a8ffaudio_output Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8ffreceive_mixer Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8ffreceive_pipeline Tff7b72= Tff7b72None
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8fftelephone Tff7b72= Te6edf3tele
Te6edf3tele_mgrTff7b72.Td2a8ffis_voicemail_session_active Tff7b72= Tff7b72False
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3client Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)

Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffattach_clientTb4b4b4(Te6edf3clientTb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Te6edf3client Tff7b72in Te6edf3bridgeTff7b72.Td2a8ffclients
Tff7b72assert Tffa657isinstanceTb4b4b4(Te6edf3bridgeTff7b72.Td2a8fftx_sourceTb4b4b4, Te6edf3WebAudioSourceTb4b4b4)
Tff7b72assert Te6edf3teleTff7b72.Td2a8ffaudio_input Tff7b72is Te6edf3bridgeTff7b72.Td2a8fftx_source
Te6edf3teleTff7b72.Td2a8fftransmit_mixerTff7b72.Td2a8ffstartTff7b72.Td2a8ffassert_called_onceTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffrx_tee Tff7b72is Tff7b72not Tff7b72None
Tff7b72assert Te6edf3teleTff7b72.Td2a8ffaudio_output Tff7b72is Te6edf3bridgeTff7b72.Td2a8ffrx_tee
Tff7b72assert Te6edf3teleTff7b72.Td2a8ffreceive_pipeline Tff7b72is Te6edf3mock_receive_pipeline
Te6edf3mock_receive_pipelineTff7b72.Td2a8ffstartTff7b72.Td2a8ffassert_called_onceTb4b4b4(Tb4b4b4)
Te6edf3mock_pipeline_clsTff7b72.Td2a8ffassert_called_onceTb4b4b4(Tb4b4b4)
Te6edf3call_kw Tff7b72= Te6edf3mock_pipeline_clsTff7b72.Td2a8ffcall_argsTff7b72.Td2a8ffkwargs
Tff7b72assert Te6edf3call_kwTb4b4b4[Ta5d6ff"Ta5d6ffsourceTa5d6ff"Tb4b4b4] Tff7b72is Te6edf3teleTff7b72.Td2a8ffreceive_mixer
Tff7b72assert Te6edf3call_kwTb4b4b4[Ta5d6ff"Ta5d6ffsinkTa5d6ff"Tb4b4b4] Tff7b72is Te6edf3bridgeTff7b72.Td2a8ffrx_tee

Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffattach_clientTb4b4b4(Te6edf3clientTb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3bridgeTff7b72.Td2a8ffclientsTb4b4b4) Tff7b72== T79c0ff1
Te6edf3mock_pipeline_clsTff7b72.Td2a8ffassert_called_onceTb4b4b4(Tb4b4b4)


Tf0883e@patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.web_audio_bridge.PipelineTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_attach_rx_tee_includes_base_sink_when_audio_output_existsTb4b4b4(Te6edf3mock_pipeline_clsTb4b4b4)Tb4b4b4:
Te6edf3mock_pipeline_clsTff7b72.Td2a8ffreturn_value Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3base_out Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8ffactive_call Tff7b72= Tffa657objectTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8fftarget_frame_time_ms Tff7b72= T79c0ff60
Te6edf3teleTff7b72.Td2a8ffaudio_input Tff7b72= Tff7b72None
Te6edf3teleTff7b72.Td2a8fftransmit_mixer Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8fftransmit_mixerTff7b72.Td2a8ffshould_run Tff7b72= Tff7b72True
Te6edf3teleTff7b72.Td2a8ffaudio_output Tff7b72= Te6edf3base_out
Te6edf3teleTff7b72.Td2a8ffreceive_mixer Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8ffreceive_pipeline Tff7b72= Tff7b72None
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8fftelephone Tff7b72= Te6edf3tele
Te6edf3tele_mgrTff7b72.Td2a8ffis_voicemail_session_active Tff7b72= Tff7b72False
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffattach_clientTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3bridgeTff7b72.Td2a8ffrx_teeTff7b72.Td2a8ffsinksTb4b4b4) Tff7b72== T79c0ff2
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffrx_teeTff7b72.Td2a8ffsinksTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72is Te6edf3base_out
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffrx_teeTff7b72.Td2a8ffsinksTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72is Te6edf3bridgeTff7b72.Td2a8ffrx_sink


Tf0883e@patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.web_audio_bridge.PipelineTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_attach_rx_tee_single_sink_when_no_base_audio_outputTb4b4b4(Te6edf3mock_pipeline_clsTb4b4b4)Tb4b4b4:
Te6edf3mock_pipeline_clsTff7b72.Td2a8ffreturn_value Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8ffactive_call Tff7b72= Tffa657objectTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8fftarget_frame_time_ms Tff7b72= T79c0ff60
Te6edf3teleTff7b72.Td2a8ffaudio_input Tff7b72= Tff7b72None
Te6edf3teleTff7b72.Td2a8fftransmit_mixer Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8fftransmit_mixerTff7b72.Td2a8ffshould_run Tff7b72= Tff7b72True
Te6edf3teleTff7b72.Td2a8ffaudio_output Tff7b72= Tff7b72None
Te6edf3teleTff7b72.Td2a8ffreceive_mixer Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8ffreceive_pipeline Tff7b72= Tff7b72None
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8fftelephone Tff7b72= Te6edf3tele
Te6edf3tele_mgrTff7b72.Td2a8ffis_voicemail_session_active Tff7b72= Tff7b72False
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffattach_clientTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3bridgeTff7b72.Td2a8ffrx_teeTff7b72.Td2a8ffsinksTb4b4b4) Tff7b72== T79c0ff1
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffrx_teeTff7b72.Td2a8ffsinksTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72is Te6edf3bridgeTff7b72.Td2a8ffrx_sink


Tff7b72def Td2a8fftest_attach_client_returns_false_when_telephone_is_noneTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8fftelephone Tff7b72= Tff7b72None
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3c Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffattach_clientTb4b4b4(Te6edf3cTb4b4b4) Tff7b72is Tff7b72False
Tff7b72assert Te6edf3c Tff7b72not Tff7b72in Te6edf3bridgeTff7b72.Td2a8ffclients


Tff7b72def Td2a8fftest_detach_client_ignores_unknown_clientTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ffclientsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72with Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(Te6edf3bridgeTb4b4b4, Ta5d6ff"Ta5d6ff_restore_host_audioTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3restoreTb4b4b4:
Te6edf3bridgeTff7b72.Td2a8ffdetach_clientTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3restoreTff7b72.Td2a8ffassert_not_calledTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8fftest_detach_non_last_client_does_not_restore_host_audioTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3cfg Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3cfgTff7b72.Td2a8fftelephone_web_audio_allow_fallbackTff7b72.Td2a8ffgetTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72True
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3cfgTb4b4b4)
Te6edf3c1Tb4b4b4, Te6edf3c2 Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ffclientsTff7b72.Td2a8ffupdateTb4b4b4(Tb4b4b4{Te6edf3c1Tb4b4b4, Te6edf3c2Tb4b4b4}Tb4b4b4)
Tff7b72with Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(Te6edf3bridgeTb4b4b4, Ta5d6ff"Ta5d6ff_restore_host_audioTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3restoreTb4b4b4:
Te6edf3bridgeTff7b72.Td2a8ffdetach_clientTb4b4b4(Te6edf3c1Tb4b4b4)
Te6edf3restoreTff7b72.Td2a8ffassert_not_calledTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3c2 Tff7b72in Te6edf3bridgeTff7b72.Td2a8ffclients


Tff7b72def Td2a8fftest_detach_last_client_restores_when_allow_fallback_enabledTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3cfg Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3cfgTff7b72.Td2a8fftelephone_web_audio_allow_fallbackTff7b72.Td2a8ffgetTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72True
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3cfgTb4b4b4)
Te6edf3c Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ffclientsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3cTb4b4b4)
Tff7b72with Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(Te6edf3bridgeTb4b4b4, Ta5d6ff"Ta5d6ff_restore_host_audioTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3restoreTb4b4b4:
Te6edf3bridgeTff7b72.Td2a8ffdetach_clientTb4b4b4(Te6edf3cTb4b4b4)
Te6edf3restoreTff7b72.Td2a8ffassert_called_onceTb4b4b4(Tb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3bridgeTff7b72.Td2a8ffclientsTb4b4b4) Tff7b72== T79c0ff0


Tff7b72def Td2a8fftest_detach_last_client_skips_restore_when_allow_fallback_disabledTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3cfg Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3cfgTff7b72.Td2a8fftelephone_web_audio_allow_fallbackTff7b72.Td2a8ffgetTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72False
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3cfgTb4b4b4)
Te6edf3c Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ffclientsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3cTb4b4b4)
Tff7b72with Te6edf3patchTff7b72.Td2a8ffobjectTb4b4b4(Te6edf3bridgeTb4b4b4, Ta5d6ff"Ta5d6ff_restore_host_audioTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3restoreTb4b4b4:
Te6edf3bridgeTff7b72.Td2a8ffdetach_clientTb4b4b4(Te6edf3cTb4b4b4)
Te6edf3restoreTff7b72.Td2a8ffassert_not_calledTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8fftest_on_call_ended_clears_clients_and_pipeline_handlesTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ffclientsTff7b72.Td2a8ffupdateTb4b4b4(Tb4b4b4{Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4}Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8fftx_source Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ffrx_sink Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ffrx_tee Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ffon_call_endedTb4b4b4(Tb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3bridgeTff7b72.Td2a8ffclientsTb4b4b4) Tff7b72== T79c0ff0
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8fftx_source Tff7b72is Tff7b72None
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffrx_sink Tff7b72is Tff7b72None
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffrx_tee Tff7b72is Tff7b72None


Tff7b72def Td2a8fftest_restore_host_audio_no_telephone_is_safeTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8fftelephone_manager Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8fftelephone_managerTff7b72.Td2a8fftelephone Tff7b72= Tff7b72None
Te6edf3bridgeTff7b72.Td2a8ffrx_tee Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ff_restore_host_audioTb4b4b4(Tb4b4b4)


Tf0883e@patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.web_audio_bridge.RNS.logTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_ensure_remote_tx_swallows_source_init_failureTb4b4b4(Te6edf3mock_logTb4b4b4)Tb4b4b4:
Te6edf3tele Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8fftransmit_mixer Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8fftransmit_mixerTff7b72.Td2a8ffshould_run Tff7b72= Tff7b72True
Te6edf3tele_mgr Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3tele_mgrTff7b72.Td2a8ffis_voicemail_session_active Tff7b72= Tff7b72False
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3tele_mgrTb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8fftx_source Tff7b72= Tff7b72None
Tff7b72with Te6edf3patchTb4b4b4(
Ta5d6ff"Ta5d6ffmeshchatx.src.backend.web_audio_bridge.WebAudioSourceTa5d6ff"Tb4b4b4,
Te6edf3side_effectTff7b72=Tf85149RuntimeErrorTb4b4b4(Ta5d6ff"Ta5d6ffinit failedTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3bridgeTff7b72.Td2a8ff_ensure_remote_txTb4b4b4(Te6edf3teleTb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8fftx_source Tff7b72is Tff7b72None
Te6edf3mock_logTff7b72.Td2a8ffassert_calledTb4b4b4(Tb4b4b4)


Tf0883e@patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.src.backend.web_audio_bridge.RNS.logTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_ensure_rx_tee_swallows_web_audio_sink_init_failureTb4b4b4(Te6edf3mock_logTb4b4b4)Tb4b4b4:
Te6edf3tele Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8ffaudio_output Tff7b72= Tff7b72None
Te6edf3teleTff7b72.Td2a8ffreceive_mixer Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3teleTff7b72.Td2a8ffreceive_pipeline Tff7b72= Tff7b72None
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ffrx_sink Tff7b72= Tff7b72None
Tff7b72with Te6edf3patchTb4b4b4(
Ta5d6ff"Ta5d6ffmeshchatx.src.backend.web_audio_bridge.WebAudioSinkTa5d6ff"Tb4b4b4,
Te6edf3side_effectTff7b72=Tf85149RuntimeErrorTb4b4b4(Ta5d6ff"Ta5d6ffsink init failedTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3bridgeTff7b72.Td2a8ff_ensure_rx_teeTb4b4b4(Te6edf3teleTb4b4b4)
Tff7b72assert Te6edf3bridgeTff7b72.Td2a8ffrx_sink Tff7b72is Tff7b72None
Te6edf3mock_logTff7b72.Td2a8ffassert_calledTb4b4b4(Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_send_bytes_to_all_detaches_stale_clientsTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3bridge Tff7b72= Te6edf3WebAudioBridgeTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3healthy_client Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3healthy_clientTff7b72.Td2a8ffsend_bytes Tff7b72= Te6edf3AsyncMockTb4b4b4(Te6edf3return_valueTff7b72=Tff7b72NoneTb4b4b4)

Te6edf3stale_client Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3stale_clientTff7b72.Td2a8ffsend_bytes Tff7b72= Te6edf3AsyncMockTb4b4b4(Te6edf3side_effectTff7b72=Tf85149RuntimeErrorTb4b4b4(Ta5d6ff"Ta5d6ffsocket closedTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3bridgeTff7b72.Td2a8ffclients Tff7b72= Tb4b4b4{Te6edf3healthy_clientTb4b4b4, Te6edf3stale_clientTb4b4b4}

Tff7b72await Te6edf3bridgeTff7b72.Td2a8ff_send_bytes_to_allTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffpcmTa5d6ff"Tb4b4b4)

Te6edf3healthy_clientTff7b72.Td2a8ffsend_bytesTff7b72.Td2a8ffassert_awaited_once_withTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffpcmTa5d6ff"Tb4b4b4)
Te6edf3stale_clientTff7b72.Td2a8ffsend_bytesTff7b72.Td2a8ffassert_awaited_once_withTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffpcmTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3stale_client Tff7b72not Tff7b72in Te6edf3bridgeTff7b72.Td2a8ffclients


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────